<template>
    <div class="video-play-page" style="width: 100%; height: 100%">
        <i class="iconfont icon-video" v-if="loading" />
        <video
            muted="muted"
            :id="id"
            style="width: 100%; height: 100%"
            :src="src"
            autoplay
        ></video>
    </div>
</template>
<script setup>
import { v4 as uuidv4 } from "uuid";
import {
    computed,
    onBeforeUnmount,
    onMounted,
    reactive,
    ref,
    watch,
} from "vue";

const props = defineProps({
    deviceId: {
        type: String,
        default: () => "34020000001320000030",
    },
    controls: {
        type: Boolean,
        default: () => false,
    },
    platformId: {
        type: String,
        default: () => "42010500002005000066",
    },
});

const wsUrl = "ws://192.168.128.104:8003"; //视频平台地址
const src = ref("");
const id = uuidv4();
const loading = ref(true);
const ws_control = ref(null);
const websocket = ref(null);
const postData = reactive({
    token: "456789",
    action: "live",
    is_local: false,
    platform_uid: props.platformId,
    device_uid: props.deviceId,
    session_id:
        parseInt(Math.random().toString() * 10e10) +
        "" +
        Date.parse(new Date()),
    trans_type: "udp",
    video: "streamv2",
});

const postData_Control_video = computed(() => {
    return {
        ...postData,
        connect_type: "control",
    };
});

const postData_Live_video = computed(() => {
    return {
        ...postData,
        connect_type: "video",
    };
});

onMounted(() => {
    loading.value = true;
});

onBeforeUnmount(() => {
    websocket.value && websocket.value.close();
});

const GetWebSocketControlURL = (url) => {
    ws_control.value = new WebSocket(url);
    ws_control.value.binaryType = "arraybuffer";
    ws_control.value.onopen = function (event) {
        console.log("websocket 连接成功!  像控制通道继续发送postData");
        Request_Live_Video();
    };

    ws_control.value.onclose = function (event) {
        console.log("websocket 已经关闭!");
        loading.value = false;
    };

    ws_control.value.onerror = function (event) {
        console.log("websocket 发生异常!");
        loading.value = false;
    };

    ws_control.value.onmessage = function (event) {
        loading.value = false;
        var jsObj = JSON.parse(event.data);
        var ws_session = jsObj.session; // 和传入的相对应
        if (
            jsObj.status == 200 &&
            ws_session == postData_Control_video.value.session_id
        ) {
            // 发送control消息成功  ，生成新的 websocket去 获取视频流媒体数据
            show(url);
        } else {
            alert(jsObj.content);
        }
        var type = jsObj.type;
        if (type == "text") {
            console.log("提示文本信息:", jsObj.content);
        } else if (type == "video_query") {
            let xmlList = [];
            xmlList = getXmlDocumentByXmlString(jsObj.content);
        } else if (type == "packet_info") {
            console.log("包统计信息:", jsObj.content);
        } else if (type == "video_fail") {
            console.log("请求失败:", jsObj.content);
        } else if ((type = "file_size")) {
            console.log("文件大小:", jsObj.content);
        }
    };
};

watch(
    () => props.deviceId,
    (newVal) => {
        if (!newVal) return;
        GetWebSocketControlURL(wsUrl);
    },
    {
        immediate: true,
    }
);

const show = (url) => {
    var mediaSource = new MediaSource();
    var mimeCodec = 'video/mp4; codecs="avc1.64001f"';
    //视频播放
    var video = document.getElementById(id);
    src.value = URL.createObjectURL(mediaSource);
    video.addEventListener("canplay", function () {
        video.play();
    });
    mediaSource.addEventListener("sourceopen", async function (e) {
        var mediaSource = e.target;
        var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
        var bufferMode = sourceBuffer.mode;
        if (bufferMode == "segments") {
            sourceBuffer.mode = "sequence";
        }
        websocket.value = new WebSocket(url);
        websocket.value.binaryType = "arraybuffer";
        websocket.value.onopen = function (evt) {
            websocket.value.send(JSON.stringify(postData_Live_video.value));
        };
        websocket.value.onclose = function (evt) {};

        var packages = new Array();

        function is_moof(d) {
            return (
                d.length > 8 &&
                d[4] == 0x6d &&
                d[5] == 0x6f &&
                d[6] == 0x6f &&
                d[7] == 0x66
            );
        }

        function is_iframe(d) {
            if (is_moof(d)) {
                return d.length > 116 && d[116] == 0x65;
            }
            return false;
        }

        var find_first_iframe = false;
        var first_frame = true;

        websocket.value.onmessage = function (evt) {
            var d = new Uint8Array(evt.data);
            if (first_frame) {
                if (d[527] == 0x67) {
                    mimeCodec =
                        'video/mp4; codecs="avc1.' +
                        d[528].toString(16) +
                        d[529].toString(16) +
                        d[530].toString(16) +
                        '"';
                }
                first_frame = false;
            }
            if (document.hidden) {
                find_first_iframe = false;
                return;
            }
            if (find_first_iframe == false && is_moof(d)) {
                if (is_iframe(d) == false) {
                    return;
                } else {
                    find_first_iframe = true;
                }
            }
            if (is_iframe(d) && packages.length >= 10) {
                packages = [];
            }
            packages.push(evt.data);
            if (sourceBuffer.updating == false && packages.length > 0) {
                try {
                    var p = packages[0];
                    sourceBuffer.appendBuffer(p);
                    packages.shift();
                } catch (e) {
                    console.log(e);
                    console.log("sourceBuffer.appendBuffer = " + e.toString());
                }
            }
        };
        websocket.value.onerror = function (evt) {};
    });
};

const Request_Live_Video = () => {
    ws_control.value.send(JSON.stringify(postData_Control_video.value));
};

const getXmlDocumentByXmlString = (xmlString) => {
    return getXmlNode(xmlString);
};

const getXmlNode = (str) => {
    //创建文档对象
    var parser = new DOMParser();
    var xmlDoc = parser.parseFromString(str, "text/xml");

    let response = xmlDoc.getElementsByTagName("Response");
    if (!response) {
        return [];
    }

    //提取数据
    let list = xmlDoc.getElementsByTagName("Item");
    let arr = [];

    for (var i = 0; i < list.length; i++) {
        var DeviceID = list[i].getElementsByTagName("DeviceID")[0].innerHTML;
        var start = list[i].getElementsByTagName("StartTime")[0].innerHTML;
        var end = list[i].getElementsByTagName("EndTime")[0].innerHTML;
        var name = list[i].getElementsByTagName("Name")[0].innerHTML;
        arr.push({
            deviceId: DeviceID,
            platformId: this.postData.platform_uid,
            StartTime: start,
            EndTime: end,
            Name: name,
        });
    }
    return arr;
};
</script>
<style lang="less" scoped>
.video-play-page {
    background: #333;
    position: relative;
    video {
        z-index: 100;
    }
    .iconfont {
        font-size: 30px;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        z-index: 99;
    }
}
</style>
